<template>
  <th-button :size="size" :type="type" :disabled="disabled" @click="printCode" @close="closeHandle">
    <slot></slot>
  </th-button>
  <th-dialog title="请选择打印设备" v-model:visible="deviceVisible">
    <template v-slot:content>
      <view class="body">
        <view class="device-list">
          <view
            class="device"
            v-for="d in setting.devices"
            :key="d.deviceId"
            :class="[d.deviceId === setting.currentDevice ? 'current' : '']"
          >
            {{ d.name }}
            <button
              v-if="d.deviceId === setting.currentDevice"
              type="success"
              size="mini"
              style="margin: 0"
            >
              已连接
            </button>
            <button
              v-else
              type="primary"
              size="mini"
              style="margin: 0"
              :loading="connectingId === d.deviceId"
              @click="onConn(d)"
            >
              连接
            </button>
          </view>
        </view>
        <view class="tip">正在搜索蓝牙设备...</view>
      </view>
    </template>
  </th-dialog>
</template>

<script setup name="CometPrintButton">
import { useSetting } from '@/stores/setting';
import thButton from './th-button.vue';
import thDialog from './th-dialog.vue';

import tsc from '../gprint/tsc.js';
import CpclPrint from '../gprint/cpc.js'


const props = defineProps({
  type: {
    type: String,
  },
  border: {
    type: [Boolean, String],
    default: false,
  },
  disabled: {
    type: [Boolean, String],
    default: false,
  },
  size: {
    type: String,
  },
  data: {
    type: Array,
    default: () => {
      return [];
    },
  },
  kind: {
    type: String,
  },
});

const closeHandle = () => {
  deviceVisible.value = false;
};
// const emit = defineEmits(['print']);

// 打印
const deviceVisible = ref(false);
const setting = useSetting();
const connectingId = ref('');

// #ifdef APP-PLUS
const searchBle = () => {
  uni.openBluetoothAdapter({
    //初始化蓝牙模块
    success(res) {
      setting.onDevice(); //监听寻找到新设备的事件
      uni.getBluetoothAdapterState({
        //获取本机蓝牙适配器状态
        success: function (res) {
          if (res.available) {
            deviceVisible.value = true;
            if (res.discovering) {
              stopFindBule();
            }
            //开始搜寻附近的蓝牙外围设备
            uni.startBluetoothDevicesDiscovery();
          } else {
            uni.showToast({
              title: '本机蓝牙不可用',
              icon: 'none',
            });
          }
        },
      });
    },
    fail() {
      uni.showToast({
        title: '请检查蓝牙是否打开',
        icon: 'none',
      });
    },
  });
};

const stopFindBule = () => {
  uni.stopBluetoothDevicesDiscovery({
    success(res) {
      console.log('停止搜索设备');
    },
  });
};

uni.onBLEConnectionStateChange((res) => {
  if (!res.connected) {
    setting.connected = false;
    setting.currentDevice = '';
    uni.closeBLEConnection({
      deviceId: res.deviceId,
    });
  }
});

//连接
const onConn = (item) => {
  let deviceId = item.deviceId;
  connectingId.value = item.deviceId;
  uni.createBLEConnection({
    //连接低功耗蓝牙设备
    deviceId: deviceId,
    timeout: 6000,
    complete(res) {
      if (res.errMsg == 'createBLEConnection:ok') {
        setTimeout(function () {
          getBLEServices(deviceId); //获取蓝牙设备所有服务(service)
        }, 2000);
      } else {
        uni.showToast({
          title: '连接超时,请重试',
          icon: 'none',
        });
        connectingId.value = '';
      }
      //连接成功 关闭搜索
      stopFindBule();
    },
  });
};

const getBLEDeviceCharacteristics = (param) => {
  return new Promise((resolve, reject) => {
    uni.getBLEDeviceCharacteristics({
      ...param,
      success(res) {
        const services = res.characteristics
          .filter((c) => c.properties.write)
          .map((c) => {
            return {
              serviceId: param.serviceId,
              characteristicId: c.uuid,
            };
          });
        resolve(services);
      },
      fail() {
        resolve(null);
      },
    });
  });
};

const getBLEServices = (deviceId) => {
  uni.getBLEDeviceServices({
    deviceId,
    success: async (res) => {
      let services = [];
      for (var s = 0; s < res.services.length; s++) {
        const serviceId = res.services[s].uuid;

        const nList = await getBLEDeviceCharacteristics({ deviceId, serviceId });
        services = [...services, ...nList];
      }

      if (services.length) {
        for (var index in setting.devices) {
          if (setting.devices[index].deviceId == deviceId) {
            setting.devices[index].services = services;
            break;
          }
        }
        setting.currentDevice = deviceId;
        setting.connected = true;
        deviceVisible.value = false;
        uni.showToast({
          title: '蓝牙连接成功',
        });
      } else {
        uni.showToast({
          title: '本机蓝牙不可用',
          icon: 'none',
        });
      }
    },
    fail(res) {
      console.log(res);
    },
  });
};

const senBlData = (deviceId, serviceId, characteristicId, uint8Array) => {
  var uint8Buf = Array.from(uint8Array);
  function split_array(datas, size) {
    var result = {};
    var j = 0;
    for (var i = 0; i < datas.length; i += size) {
      result[j] = datas.slice(i, i + size);
      j++;
    }
    return result;
  }
  var sendloop = split_array(uint8Buf, 20);
  return new Promise((resolve, reject) => {
    function realWriteData(sendloop, i) {
      var data = sendloop[i];
      if (typeof data == 'undefined') {
        resolve('一次打印已结束');
        return;
      }
      var buffer = new ArrayBuffer(data.length);
      var dataView = new DataView(buffer);
      for (var j = 0; j < data.length; j++) {
        dataView.setUint8(j, data[j]);
      }
      uni.writeBLECharacteristicValue({
        deviceId,
        serviceId,
        characteristicId,
        value: buffer,
        success(res) {
          realWriteData(sendloop, i + 1);
        },
      });
    }
    var i = 0;
    realWriteData(sendloop, i);
  });
};

const sendPrint = (data) => {
  return new Promise((resolve, reject) => {
    const currDev = setting.devices.find((d) => setting.currentDevice === d.deviceId);
    let deviceId = currDev.deviceId;
    let serviceId = currDev.services[0].serviceId;
    let characteristicId = currDev.services[0].characteristicId;

    const {
	  id,
	  demandCode,
      checkCode,
      invName,
      sampleBatch,
      processName,
      invStd,
      sampleCode,
      reportCode,
      analysisName,
      itemName,
    } = data;


    // 汉印
    if (currDev.name.indexOf('HM') === 0) {
      var cpcl = new CpclPrint('标签打印');
      cpcl.setPage();
      switch (props.kind) {
        case 'qcMiddleCheck':
          // 实验报检
          cpcl.addText(3, 1, 16, 8, `产品名称: ${invName}`);
          cpcl.addText(3, 1, 16, 40, `报检单号: ${checkCode}`);
          cpcl.addText(3, 1, 280, 40, `样品批号: ${sampleBatch || ''}`);
          cpcl.addText(3, 1, 16, 72, `工序: ${processName || ''}`);
          cpcl.addText(3, 1, 280, 72, `规格: ${invStd || ''}`);
          cpcl.addText(3, 1, 16, 104, `检测指标: ${itemName || ''}`);
          cpcl.addBarcode(39, 1, 1, 50, 16, 136, `${checkCode}`);
          cpcl.addText(3, 1, 16, 194, `${checkCode}`);
          break;
        case 'qcExoticCheck':
          // 任务报检
          cpcl.addText(3, 1, 16, 8, `报检单号:${checkCode}`);
          cpcl.addText(3, 1, 16, 40, `样品编码: ${sampleCode || ''}`);
          cpcl.addText(3, 1, 300, 40, `样品批号: ${sampleBatch || ''}`);
          cpcl.addText(3, 1, 16, 72, `规格: ${invStd || ''}`);
          cpcl.addText(3, 1, 16, 104, `检测指标: ${itemName || ''}`);
          cpcl.addBarcode(39, 1, 1, 50, 16, 136, `${checkCode}`);
          cpcl.addText(3, 1, 16, 194, `${checkCode}`);
          break;
        case 'checkReport':
          // 报告单打印
          cpcl.addText(3, 1, 16, 8, `报告单号: ${reportCode}`);
          cpcl.addText(3, 1, 16, 40, `分析手段: ${analysisName || ''}`);
          cpcl.addText(3, 1, 16, 72, `检测指标: ${itemName || ''}`);
          cpcl.addBarcode(39, 1, 1, 50, 16, 104, `${reportCode}`);
          cpcl.addText(3, 1, 16, 162, `${reportCode}`);
          break;
		case 'demand':
		  // 来样打印
		  cpcl.addText(3, 1, 16, 8, `需求单号: ${demandCode}`);
		  cpcl.addText(3, 1, 16, 40, `产品名称: ${invName || ''}`);
		  cpcl.addText(3, 1, 16, 72, `批号: ${sampleBatch || ''}`);
		  cpcl.addText(3, 1, 16, 104, `规格: ${invStd || ''}`);
		  cpcl.addBarcode(128, 1, 1, 50, 16, 136, `s${id}e`);
		  break;
        default:
          break;
      }

      cpcl.addForm();
      cpcl.addPrint();
      senBlData(deviceId, serviceId, characteristicId, cpcl.getCommand()).then((res) => {
        resolve(res);
      });
    } else {
      var command = tsc.createNew();
      command.setSize(152, 30);
      command.setGap(2);
      command.setCls();

      switch (props.kind) {
        // 实验报检
        case 'qcMiddleCheck':
          command.setText(16, 8, 'TSS16.BF2', 1, 1, `产品名称: ${invName}`);
          command.setText(16, 40, 'TSS16.BF2', 1, 1, `报检单号: ${checkCode}`);
          command.setText(280, 40, 'TSS16.BF2', 1, 1, `样品批号: ${sampleBatch || ''}`);
          command.setText(16, 72, 'TSS16.BF2', 1, 1, `工序: ${processName || ''}`);
          command.setText(280, 72, 'TSS16.BF2', 1, 1, `规格: ${invStd || ''}`);
          command.setText(16, 104, 'TSS16.BF2', 1, 1, `检测指标: ${itemName || ''}`);
          command.setBarCode(16, 136, '128M', 48, 1, 2, 2, `${checkCode}`);
          break;
        // 任务报检
        case 'qcExoticCheck':
          command.setText(16, 8, 'TSS16.BF2', 1, 1, `报检单号: ${checkCode}`);
          command.setText(16, 40, 'TSS16.BF2', 1, 1, `样品编码: ${sampleCode}`);
          command.setText(300, 40, 'TSS16.BF2', 1, 1, `样品批号: ${sampleBatch}`);
          command.setText(16, 72, 'TSS16.BF2', 1, 1, `规格: ${invStd || ''}`);
          command.setText(16, 104, 'TSS16.BF2', 1, 1, `检测指标: ${itemName || ''}`);
          command.setBarCode(16, 136, '128M', 48, 1, 2, 2, `${checkCode}`);
          break;
        // 检验报告
        case 'checkReport':
          command.setText(16, 8, 'TSS16.BF2', 1, 1, `报告单号: ${reportCode}`);
          command.setText(16, 40, 'TSS16.BF2', 1, 1, `分析手段: ${analysisName}`);
          command.setText(16, 72, 'TSS16.BF2', 1, 1, `检测指标: ${itemName}`);
          command.setBarCode(16, 104, '128M', 52, 1, 2, 2, `${reportCode}`);
          break;
        default:
          break;
      }

      command.setPagePrint();
      senBlData(deviceId, serviceId, characteristicId, command.getData()).then((res) => {
        resolve(res);
      });
    }
  });
};

const printCode = async () => {
  if (setting.connected) {
    for (let i = 0; i < props.data.length; i++) {
      await sendPrint(props.data[i]);
    }
  } else {
    searchBle();
  }
};
// #endif
</script>

<style lang="scss" scoped>
.body {
  // height:;
  .tip {
    text-align: center;
    padding: 20rpx;
    font-size: 26rpx;
  }
}
.device-list {
  max-height: 70vh;
  .device {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 15rpx;
    border-bottom: 1rpx solid #f2f2f2;
    &.current {
      color: #007aff;
    }
  }
}
</style>
